﻿#include "SoundManager.h"
#include "../Program.h"
#include "../Settings.h"
#include "Libraries/WavLibrary.h"
#include "Libraries/NullLibrary.h"

using namespace SlimDX::DirectSound;

namespace Client::MirSounds
{

DirectSound *SoundManager::Device;
std::vector<ISoundLibrary*> SoundManager::Sounds;
std::unordered_map<int, std::string> SoundManager::IndexList;
ISoundLibrary *SoundManager::Music;
int SoundManager::_vol = 0;

    int SoundManager::getVol()
    {
        return _vol;
    }

    void SoundManager::setVol(int value)
    {
        if (_vol == value)
        {
            return;
        }
        _vol = value;
        AdjustAllVolumes();
    }

int SoundManager::_musicVol = 0;

    int SoundManager::getMusicVol()
    {
        return _musicVol;
    }

    void SoundManager::setMusicVol(int value)
    {
        if (_musicVol == value)
        {
            return;
        }
        _musicVol = value;
    }

    void SoundManager::Create()
    {
        if (Program::Form == nullptr || Program::Form->IsDisposed)
        {
            return;
        }

        Device = new DirectSound();
        Device->SetCooperativeLevel(Program::Form->Handle, CooperativeLevel::Normal);
        Device->IsDefaultPool = false;

        LoadSoundList();
    }

    void SoundManager::LoadSoundList()
    {
        std::string fileName = FileSystem::combine(Settings::SoundPath, "SoundList.lst");

        if (!FileSystem::fileExists(fileName))
        {
            return;
        }

        std::vector<std::string> lines = File::ReadAllLines(fileName);

        for (int i = 0; i < lines.size(); i++)
        {
            std::vector<std::string> split = StringHelper::replace(lines[i], " ", "")->Split(':', '\t');

            int index;
            if (split.size() <= 1 || !int::TryParse(split[0], index))
            {
                continue;
            }

            if (IndexList.find(index) == IndexList.end())
            {
                IndexList.emplace(index, split[split.size() - 1]);
            }
        }

    }

    void SoundManager::StopSound(int index)
    {
        for (int i = 0; i < Sounds.size(); i++)
        {
            if (Sounds[i]->getIndex() != index)
            {
                continue;
            }

            Sounds[i]->Stop();
            return;
        }
    }

    void SoundManager::PlaySound(int index, bool loop)
    {
        if (Device == nullptr)
        {
            return;
        }

        if (_vol <= -3000)
        {
            return;
        }

        for (int i = 0; i < Sounds.size(); i++)
        {
            if (Sounds[i]->getIndex() != index)
            {
                continue;
            }
            Sounds[i]->Play();
            return;
        }

        if (IndexList.find(index) != IndexList.end())
        {
            Sounds.push_back(GetSound(index, IndexList[index], loop));
        }
        else
        {
            std::string filename;
            if (index > 20000)
            {
                index -= 20000;
                filename = std::string::Format("M{0:0}-{1:0}", index / 10, index % 10);

                Sounds.push_back(GetSound(index + 20000, filename, loop));
            }
            else if (index < 10000)
            {
                filename = std::string::Format("{0:000}-{1:0}", index / 10, index % 10);

                auto sound = GetSound(index, filename, loop);

                Sounds.push_back(GetSound(index, filename, loop));
            }
        }
    }

    void SoundManager::PlayMusic(int index, bool loop)
    {
        if (Device == nullptr)
        {
            return;
        }

        Music = GetSound(index, std::to_string(index), true);
        Music->SetVolume(getMusicVol());
        Music->Play();
    }

    void SoundManager::AdjustAllVolumes()
    {
        for (int i = 0; i < Sounds.size(); i++)
        {
            Sounds[i]->Dispose();
        }
        Sounds.clear();
    }

    ISoundLibrary *SoundManager::GetSound(int index, const std::string &fileName, bool loop)
    {
        auto sound = WavLibrary::TryCreate(index, fileName, loop);

        if (sound != nullptr)
        {
            return sound;
        }

        return new NullLibrary(index, fileName, loop);
    }

int SoundList::None = 0;
int SoundList::Music = 0;
int SoundList::IntroMusic = 10146;
int SoundList::SelectMusic = 10147;
int SoundList::LoginEffect = 10100;
int SoundList::ButtonA = 10103;
int SoundList::ButtonB = 10104;
int SoundList::ButtonC = 10105;
int SoundList::Gold = 10106;
int SoundList::EatDrug = 10107;
int SoundList::ClickDrug = 10108;
int SoundList::Teleport = 10110;
int SoundList::LevelUp = 10156;
int SoundList::ClickWeapon = 10111;
int SoundList::ClickArmour = 10112;
int SoundList::ClickRing = 10113;
int SoundList::ClickBracelet = 10114;
int SoundList::ClickNecklace = 10115;
int SoundList::ClickHelmet = 10116;
int SoundList::ClickBoots = 10117;
int SoundList::ClickItem = 10118;
int SoundList::WalkGroundL = 10001;
int SoundList::WalkGroundR = 10002;
int SoundList::RunGroundL = 10003;
int SoundList::RunGroundR = 10004;
int SoundList::WalkStoneL = 10005;
int SoundList::WalkStoneR = 10006;
int SoundList::RunStoneL = 10007;
int SoundList::RunStoneR = 10008;
int SoundList::WalkLawnL = 10009;
int SoundList::WalkLawnR = 10010;
int SoundList::RunLawnL = 10011;
int SoundList::RunLawnR = 10012;
int SoundList::WalkRoughL = 10013;
int SoundList::WalkRoughR = 10014;
int SoundList::RunRoughL = 10015;
int SoundList::RunRoughR = 10016;
int SoundList::WalkWoodL = 10017;
int SoundList::WalkWoodR = 10018;
int SoundList::RunWoodL = 10019;
int SoundList::RunWoodR = 10020;
int SoundList::WalkCaveL = 10021;
int SoundList::WalkCaveR = 10022;
int SoundList::RunCaveL = 10023;
int SoundList::RunCaveR = 10024;
int SoundList::WalkRoomL = 10025;
int SoundList::WalkRoomR = 10026;
int SoundList::RunRoomL = 10027;
int SoundList::RunRoomR = 10028;
int SoundList::WalkWaterL = 10029;
int SoundList::WalkWaterR = 10030;
int SoundList::RunWaterL = 10031;
int SoundList::RunWaterR = 10032;
int SoundList::HorseWalkL = 10033;
int SoundList::HorseWalkR = 10034;
int SoundList::HorseRun = 10035;
int SoundList::WalkSnowL = 10036;
int SoundList::WalkSnowR = 10037;
int SoundList::RunSnowL = 10038;
int SoundList::RunSnowR = 10039;
int SoundList::SwingShort = 10050;
int SoundList::SwingWood = 10051;
int SoundList::SwingSword = 10052;
int SoundList::SwingSword2 = 10053;
int SoundList::SwingAxe = 10054;
int SoundList::SwingClub = 10055;
int SoundList::SwingLong = 10056;
int SoundList::SwingFist = 10056;
int SoundList::StruckShort = 10060;
int SoundList::StruckWooden = 10061;
int SoundList::StruckSword = 10062;
int SoundList::StruckSword2 = 10063;
int SoundList::StruckAxe = 10064;
int SoundList::StruckClub = 10065;
int SoundList::StruckBodySword = 10070;
int SoundList::StruckBodyAxe = 10071;
int SoundList::StruckBodyLongStick = 10072;
int SoundList::StruckBodyFist = 10073;
int SoundList::StruckArmourSword = 10080;
int SoundList::StruckArmourAxe = 10081;
int SoundList::StruckArmourLongStick = 10082;
int SoundList::StruckArmourFist = 10083;
int SoundList::MaleFlinch = 10138;
int SoundList::FemaleFlinch = 10139;
int SoundList::MaleDie = 10144;
int SoundList::FemaleDie = 10145;
int SoundList::Revive = 20791;
int SoundList::ZombieRevive = 0705;
int SoundList::MountWalkL = 10176;
int SoundList::MountWalkR = 10177;
int SoundList::MountRun = 10178;
int SoundList::TigerStruck1 = 10179;
int SoundList::TigerStruck2 = 10180;
int SoundList::TigerAttack1 = 10181;
int SoundList::TigerAttack2 = 10182;
int SoundList::TigerAttack3 = 10183;
int SoundList::FishingThrow = 10184;
int SoundList::FishingPull = 10185;
int SoundList::Fishing = 10186;
int SoundList::WolfRide1 = 10188;
int SoundList::WolfRide2 = 10189;
int SoundList::WolfAttack1 = 10190;
int SoundList::WolfAttack2 = 10191;
int SoundList::WolfAttack3 = 10192;
int SoundList::WolfStruck1 = 10193;
int SoundList::WolfStruck2 = 10194;
int SoundList::TigerRide1 = 10218;
int SoundList::TigerRide2 = 10219;
int SoundList::PetPig = 10500;
int SoundList::PetChick = 10501;
int SoundList::PetKitty = 10502;
int SoundList::PetSkeleton = 10503;
int SoundList::PetPigman = 10504;
int SoundList::PetWemade = 10505;
int SoundList::PetBlackKitten = 10506;
int SoundList::PetDragon = 10507;
int SoundList::PetOlympic = 10508;
int SoundList::PetFrog = 10510;
int SoundList::PetMonkey = 10511;
int SoundList::PetAngryBird = 10512;
int SoundList::PetFoxey = 10513;
int SoundList::PetMedicalRat = 10514;
int SoundList::PetPickup = 10520;
}
